package com.example.opengldemo.buffer;

import android.annotation.SuppressLint;
import android.content.Context;
import android.opengl.GLES30;
import android.opengl.GLSurfaceView;
import android.view.MotionEvent;
import android.view.SurfaceHolder;

import com.example.opengldemo.R;
import com.example.opengldemo.util.MatrixState;
import com.example.opengldemo.util.TextureUtil;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

@SuppressLint("ClickableViewAccessibility")
class MySurfaceView extends GLSurfaceView {
    
	private final float TOUCH_SCALE_FACTOR = 180.0f/320;
	private float mPreviousY;
    private float mPreviousX;
	
	private float cameraX=0;
	private float cameraY=30;
	private float cameraZ=0;
	
	private float targetX=0;
	private float targetY=0;
	private float targetZ=0;
	
	private float sightDis=26;
	private float angdegElevation=90;
	private float angdegAzimuth=0;
    
	private SceneRenderer mRenderer;
    int texFloorId;
    int texWallId;

    BallGoThread ballGoThread;

	public MySurfaceView(Context context) {
        super(context);
        this.setEGLContextClientVersion(3);
        mRenderer = new SceneRenderer();
        setRenderer(mRenderer);
        setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
    }
    @Override
    public boolean onTouchEvent(MotionEvent e) {
        float y = e.getY();
        float x = e.getX();
        switch (e.getAction()) {
        case MotionEvent.ACTION_MOVE:
            float dy = y - mPreviousY;
            float dx = x - mPreviousX;

            angdegAzimuth += dx * TOUCH_SCALE_FACTOR;
            angdegElevation+= dy * TOUCH_SCALE_FACTOR;
            if(angdegElevation>=90){
            	angdegElevation=90;
            }else if(angdegElevation<=0){
            	angdegElevation=0;
            }
        }
        mPreviousY = y;
        mPreviousX = x;
        return true;
    }

	private class SceneRenderer implements Renderer
    {
		CubeGroup cubeGroup;
		BallForControl ballForControl;
		public void onDrawFrame(GL10 gl)
        {
            GLES30.glClear( GLES30.GL_DEPTH_BUFFER_BIT | GLES30.GL_COLOR_BUFFER_BIT);
            double angradElevation=Math.toRadians(angdegElevation);
        	double angradAzimuth=Math.toRadians(angdegAzimuth);
            cameraX=(float) (targetX+sightDis*Math.cos(angradElevation)*Math.sin(angradAzimuth));
            cameraY=(float) (targetY+sightDis*Math.sin(angradElevation));
            cameraZ=(float) (targetZ+sightDis*Math.cos(angradElevation)*Math.cos(angradAzimuth));

            MatrixState.setCamera(
            		cameraX,
            		cameraY,
            		cameraZ,

            		targetX,
            		targetY,
            		targetZ,

            		0,
            		1,
            		0
            );

            MatrixState.pushMatrix();
            cubeGroup.drawSelf(texFloorId,texWallId);
            MatrixState.popMatrix();

            MatrixState.pushMatrix();

            ballForControl.drawSelf();
            MatrixState.popMatrix();

        }

        @SuppressLint("NewApi")
		public void onSurfaceChanged(GL10 gl, int width, int height) {

        	GLES30.glViewport(0, 0, width, height);

            float ratio= (float) width / height;

            MatrixState.setProjectFrustum(-ratio, ratio, -1, 1, 4f, 100);

	        MatrixState.setLightLocation(0 , 12 , 0);

	        ballGoThread=new BallGoThread(ballForControl);
	        ballGoThread.setFlag(true);
	        ballGoThread.start();

        }

		public void onSurfaceCreated(GL10 gl, EGLConfig config) {

            GLES30.glClearColor(0.0f,0.0f,0.0f, 1.0f);
            GLES30.glEnable(GLES30.GL_DEPTH_TEST);
            GLES30.glEnable(GLES30.GL_CULL_FACE);
            MatrixState.setInitStack();

            texFloorId= TextureUtil.getTextureId( MySurfaceView.this , R.drawable.tex_floor , null , false);
            texWallId= TextureUtil.getTextureId( MySurfaceView.this , R.drawable.tex_wall , null , false);

            cubeGroup=new CubeGroup(MySurfaceView.this, Constant.SCALE,
            		Constant.CUBE_LENGTH, Constant.CUBE_HEIGHT, Constant.CUBE_WIDTH , Constant.WALL_WIDTH);

            ballForControl=new BallForControl(MySurfaceView.this, Constant.SCALE, Constant.AHALF,5);

            
            
        }
    }
	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		ballGoThread.setFlag(false);
	}

}
